using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Drawing;
using System.Diagnostics;
using System.Windows.Forms;

namespace Janus.NorthwindDemo2007
{
	public partial class DataProvider
	{

		protected bool mDataLoaded;
		private System.Data.OleDb.OleDbDataAdapter mDataAdapter;

		//intended to be set by inheritors. If a class that inherits from
		//DataProvider does not set this property an exception will be thrown
		//filling or updating data
		public System.Data.OleDb.OleDbDataAdapter DataAdapter
		{
			get
			{
				return mDataAdapter;
			}
			set
			{
				if (mDataAdapter != value)
				{
                    if (mDataAdapter != null)
                    {
                        mDataAdapter.RowUpdated -= new System.Data.OleDb.OleDbRowUpdatedEventHandler(mDataAdapter_RowUpdated);
                    }
					mDataAdapter = value;
                    if (mDataAdapter != null)
                    {
                        mDataAdapter.RowUpdated += new System.Data.OleDb.OleDbRowUpdatedEventHandler(mDataAdapter_RowUpdated);
                    }
				}
			}
		}

		public NorthwindData DataSet
		{
			get
			{
				return mDataSet;
			}
		}
		public void Fill()
		{
			if (! mDataLoaded)
			{
				if (FillCore())
				{
					mDataLoaded = true;
				}
				else
				{
					throw new Exception("Data was not loaded.");
				}
			}
		}
		protected virtual bool FillCore()
		{
			return false;
		}


		public bool Update()
		{
			if (! mDataLoaded)
			{
				//if data is not loaded there are no changes and you
				//can return true
				return true;
			}
			try
			{
				return UpdateCore();
			}
			catch (Exception exc)
			{
				MessageBox.Show(this.GetExceptionMessage(exc), NorthwindApp.MessageCaption, MessageBoxButtons.OK, MessageBoxIcon.Error);
				return false;
			}
		}
		protected virtual bool UpdateCore()
		{
			return false;
		}
		public bool UpdateDataRow(DataRow row)
		{
			try
			{
				if (UpdateDataRowCore(row))
				{
					if (mDataLoaded)
					{
						this.DataSet.Tables[row.Table.TableName].LoadDataRow(row.ItemArray, true);
					}
					return true;
				}
			}
			catch (Exception exc)
			{
				MessageBox.Show(GetExceptionMessage(exc), NorthwindApp.MessageCaption, MessageBoxButtons.OK, MessageBoxIcon.Error);
			}
			return false;
		}
		protected virtual bool UpdateDataRowCore(DataRow row)
		{
			return false;
		}
		public bool DeleteDataRow(DataRow row)
		{
			try
			{
				DataRow rowToDelete = null;
				if (mDataLoaded)
				{
					//find the row in the table using the primary key
					DataTable table = DataSet.Tables[row.Table.TableName];
					object[] pkValues = new object[table.PrimaryKey.Length];

                    for (int i = 0; i < pkValues.Length; i++)
					{
						pkValues[i] = row[table.PrimaryKey[i].ColumnName];
					}
					rowToDelete = table.Rows.Find(pkValues);
				}
				else
				{
					rowToDelete = row;
				}
				rowToDelete.Delete();
				return this.UpdateDataRowCore(row);
			}
			catch (Exception exc)
			{
				MessageBox.Show(GetExceptionMessage(exc), NorthwindApp.MessageCaption, MessageBoxButtons.OK, MessageBoxIcon.Error);
				return false;
			}
		}
		protected virtual bool DeleteDataRowCore(DataRow row)
		{
			return false;
		}
		//inheritors can customize the exception message overriding this function
		protected virtual string GetExceptionMessage(Exception e)
		{
			return e.Message;
		}

		private void mDataAdapter_RowUpdated(object sender, System.Data.OleDb.OleDbRowUpdatedEventArgs e)
		{
			OnRowUpdated(e);
		}

		protected virtual void OnRowUpdated(System.Data.OleDb.OleDbRowUpdatedEventArgs e)
		{
			if (e.Status != UpdateStatus.ErrorsOccurred)
			{
				if (e.StatementType != StatementType.Delete)
				{
					e.Row.AcceptChanges();
				}
			}
			else
			{
				e.Row.RejectChanges();
			}
		}

	}

} //end of root namespace